package client;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * Thread that listens to an Udp-DatagramSocket and writes to stdout
 */
public class UDPListenerThread implements Runnable,Stoppable
{
	private static int MAX_UDP_LENGTH=64*1024;
	private static String IN_NEW_BID="!new-bid";
	private static String OUT_NEW_BID="You have been overbid on '%s'";
	private static String IN_AUCTION_END="!auction-ended";
	private static String OUT_AUCTION_END="The auction '%s' has ended, no bidders";
	private static String OUT_AUCTION_WON="%s won with %s!";
	
	private DatagramSocket socket;
	private boolean bStopped;
	private String strCurrentUser;

	/**
	 * The thread is listening on socket until it is closed;
	 * @param socket DatagramSocket to listen on
	 * @param strCurrentUser String, the current User is needed to detect if an the user is owner or winner of an ended Auction.
	 * @throws SocketException
	 */
	public UDPListenerThread(int udpPort,String strCurrentUser) throws SocketException
	{
		this.socket=new DatagramSocket(udpPort);
		this.bStopped=false;
		this.strCurrentUser=strCurrentUser;
	}
	
	@Override
	public void run()
	{
		byte[] buff=new byte[MAX_UDP_LENGTH];
		DatagramPacket packet=new DatagramPacket(buff,buff.length);
		try 
		{
			while(!bStopped)
			{
				socket.receive(packet);
				System.out.println(processInput(new String(packet.getData(),0,packet.getLength())));// new String(packet.getData(),0,packet.getLength()));
			}
		}
		catch (IOException e) 
		{
			System.out.println("IOException occured while listening for Notifications "+e.getMessage());
		}
		System.out.println("UDPListenerThread stops...");
	}
	
	/**
	 * Processes the received machine-readable-notification-texts and transforms them to user-readable-texts
	 * @param input String machine-readable-notification-text
	 * @return String user-readable-text
	 */
	public String processInput(String input)
	{
		String strInput[]=input.split(" ");
		try
		{
			if(strInput[0].equals(IN_NEW_BID))
			{
				String strDesc=input.substring(strInput[0].length());
				return String.format(OUT_NEW_BID, strDesc);
			}
			else if(strInput[0].equals(IN_AUCTION_END))
			{
				String strDesc=input.substring(strInput[0].length()+strInput[1].length()+strInput[2].length()+3);
				if(strInput[1].equals(this.strCurrentUser))
				{
					strInput[1]="You";
				}
				String strRet=String.format(OUT_AUCTION_END,strDesc);
				if(!strInput[2].equals("0.00"))
				{
					strRet+=" "+String.format(OUT_AUCTION_WON, strInput[1],strInput[2]);
				}
				return strRet;
			}
			else
			{
				return "Unknown notification:'"+input+"'!";
			}
		}
		catch(IndexOutOfBoundsException ex)
		{
			return "Invalid notification:'"+input+"'!";
		}
	}
	
	@Override
	public synchronized void stop() 
	{
		this.bStopped=true;
		if(!this.socket.isClosed())
		{
			this.socket.close();
		}
	}
}
